/**
 * 编号生成工具函数
 * 按照项目风格编写的通用编号生成器
 */

import { ElMessage } from 'element-plus'
import axios from 'axios'

/**
 * 生成随机数字
 * @param min 最小值
 * @param max 最大值
 * @returns 随机数字字符串
 */
export const generateRandomNumber = (min: number = 100, max: number = 999): string => {
    return String(Math.floor(Math.random() * (max - min + 1)) + min)
}

/**
 * 生成仓库编号 (CKBH + 随机3位数字)
 * @param existingCodes 已存在的编号列表
 * @returns 生成的编号
 */
export const generateStorageCode = async (existingCodes: string[] = []): Promise<string> => {
    try {
        let newCode: string
        let attempts = 0
        const maxAttempts = 100 // 最大尝试次数，防止无限循环

        do {
            newCode = `CKBH${generateRandomNumber()}`
            attempts++
            
            // 如果尝试次数过多，说明可能没有可用的编号
            if (attempts > maxAttempts) {
                ElMessage.error('无法生成唯一编号，请稍后重试')
                throw new Error('无法生成唯一编号')
            }
        } while (existingCodes.includes(newCode))

        return newCode
    } catch (error) {
        console.error('生成仓库编号失败:', error)
        throw error
    }
}

/**
 * 生成入库单号 (RKDH + 年月日 + 随机数)
 * @returns 生成的入库单号
 */
export const generateInboundCode = (): string => {
    const now = new Date()
    const pad = (n: number) => n.toString().padStart(2, '0')
    const dateStr = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`
    const rand = Math.floor(1000 + Math.random() * 9000)
    return `RKDH${dateStr}${rand}`
}

/**
 * 生成盘点单号 (PDDH + 年月日时分秒 + 3位随机数)
 * @returns 生成的盘点单号
 */
export const generateInventoryCode = (): string => {
    const now = new Date()
    const pad = (n: number) => n.toString().padStart(2, '0')
    const dateStr = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`
    const rand = Math.floor(Math.random() * 1000).toString().padStart(3, '0')
    return `PDDH${dateStr}${rand}`
}

/**
 * 生成出库单号 (CK + 年月日时分秒)
 * @returns 生成的出库单号
 */
export const generateDeliveryCode = (): string => {
    const now = new Date()
    const pad = (n: number) => n.toString().padStart(2, '0')
    const year = now.getFullYear()
    const month = pad(now.getMonth() + 1)
    const day = pad(now.getDate())
    const hour = pad(now.getHours())
    const minute = pad(now.getMinutes())
    const second = pad(now.getSeconds())
    return `CK${year}${month}${day}${hour}${minute}${second}`
}

/**
 * 生成流水号 (YF + 年月日时分秒毫秒)
 * @returns 生成的流水号
 */
export const generateFlowingWaterNumber = (): string => {
    const now = new Date()
    const year = now.getFullYear()
    const month = String(now.getMonth() + 1).padStart(2, "0")
    const day = String(now.getDate()).padStart(2, "0")
    const hours = String(now.getHours()).padStart(2, "0")
    const minutes = String(now.getMinutes()).padStart(2, "0")
    const seconds = String(now.getSeconds()).padStart(2, "0")
    const milliseconds = String(now.getMilliseconds()).padStart(3, "0")
    return `YF${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}`
}

/**
 * 获取已存在的仓库编号列表
 * @returns 已存在的编号数组
 */
export const fetchExistingStorageCodes = async (): Promise<string[]> => {
    try {
        const response = await axios.get('http://localhost:5212/api/Storage/GetStorage', {
            params: {
                PageIndex: 1,
                PageSize: 1000 // 获取所有仓库编号
            }
        })
        
        if (response.data.code === 200) {
            return response.data.data.map((item: any) => item.storageCode)
        }
        return []
    } catch (error) {
        console.error('获取已存在编号失败:', error)
        // 如果获取失败，使用一些示例编号作为备用
        return ['CKBH1358', 'CKBH8607', 'CKBH1234', 'CKBH5678']
    }
}

/**
 * 通用编号生成器
 * @param prefix 编号前缀
 * @param length 随机数字长度
 * @param existingCodes 已存在的编号列表
 * @returns 生成的编号
 */
export const generateCustomCode = async (
    prefix: string, 
    length: number = 3, 
    existingCodes: string[] = []
): Promise<string> => {
    try {
        let newCode: string
        let attempts = 0
        const maxAttempts = 100

        do {
            const randomNum = Math.floor(Math.random() * Math.pow(10, length))
            newCode = `${prefix}${randomNum.toString().padStart(length, '0')}`
            attempts++
            
            if (attempts > maxAttempts) {
                ElMessage.error('无法生成唯一编号，请稍后重试')
                throw new Error('无法生成唯一编号')
            }
        } while (existingCodes.includes(newCode))

        return newCode
    } catch (error) {
        console.error('生成编号失败:', error)
        throw error
    }
}

/**
 * 验证编号格式
 * @param code 编号
 * @param pattern 正则表达式模式
 * @returns 是否有效
 */
export const validateCodeFormat = (code: string, pattern: RegExp): boolean => {
    return pattern.test(code)
}

/**
 * 仓库编号格式验证
 * @param code 仓库编号
 * @returns 是否有效
 */
export const validateStorageCode = (code: string): boolean => {
    return validateCodeFormat(code, /^CKBH\d{3}$/)
}

/**
 * 入库单号格式验证
 * @param code 入库单号
 * @returns 是否有效
 */
export const validateInboundCode = (code: string): boolean => {
    return validateCodeFormat(code, /^RKDH\d{12}$/)
}

/**
 * 盘点单号格式验证
 * @param code 盘点单号
 * @returns 是否有效
 */
export const validateInventoryCode = (code: string): boolean => {
    return validateCodeFormat(code, /^PDDH\d{17}$/)
}
